package com.woniuxy.core.service.impl;

import com.woniuxy.core.service.LikeService;
import com.woniuxy.enums.redis.user.LikeRedisKeyEnum;
import com.woniuxy.mq.message.LikeMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * @author 饶志
 * @version 1.0
 * @since 2025-07-15  10:10
 */
@Service
@RequiredArgsConstructor
public class LikeServiceImpl implements LikeService {

    // 用于执行Lua脚本
    private final StringRedisTemplate stringRedisTemplate;

    private final RabbitTemplate rabbitTemplate;

    // MQ队列名称
    private static final String LIKE_QUEUE = "like_queue";


    @Override
    public Long toggleLike(Long userId, Long targetId, Integer targetType) {

        // 构建Redis键
        String statusKey = LikeRedisKeyEnum.LIKE_STATUS.format(targetType, targetId);
        String countKey = LikeRedisKeyEnum.LIKE_COUNT.format(targetType, targetId);
        String userIdStr = userId.toString();

        // 使用Lua脚本保证原子性（HSET + INCR/DECR）
        String luaScript = """
                local status = redis.call('HGET', KEYS[1], ARGV[1])
                local newStatus, newCount
                if status == false or status == '0' then
                    newStatus = '1'
                    newCount = redis.call('INCR', KEYS[2])
                else
                    newStatus = '0'
                    newCount = redis.call('DECR', KEYS[2])
                end
                redis.call('HSET', KEYS[1], ARGV[1], newStatus)
                return {newStatus, newCount}
                """; // 返回状态和新计数

        RedisScript<List> script = RedisScript.of(luaScript, List.class);
        List<String> keys = Arrays.asList(statusKey, countKey);
        List<Object> result = stringRedisTemplate.execute(script, keys, userIdStr);

        // 解析结果
        Integer newStatus = Integer.parseInt(result.get(0).toString());
        Long newCount = Long.parseLong(result.get(1).toString());

        // 发送异步消息到MQ
        LikeMessage message = new LikeMessage();
        message.setUserId(userId);
        message.setTargetId(targetId);
        message.setTargetType(targetType);
        message.setStatus(newStatus);
        rabbitTemplate.convertAndSend(
                LIKE_QUEUE,
                message,
                messagePostProcessor -> {
                    // 设置消息ID用于幂等
                    messagePostProcessor.getMessageProperties()
                            .setMessageId(UUID.randomUUID().toString());
                    return messagePostProcessor;
                });

        return newCount;
    }
}
